<template>
  <div class="com-container" @dblclick="revertMap">
    <div class="com-chart" ref="map_ref"></div>
  </div>
</template>

<script setup lang="ts">
import { getCurrentInstance, ref, onMounted, onUnmounted } from "vue";
// import map from "@/assets/static/map/china.json";
import axios from "axios";
import { getProvinceMapInfo } from "@/utils/map_utils.ts";
import { getThemeValue } from "@/utils/theme_utils.ts";
import { useThemeChart } from "@/hooks/useThemeChart.ts";

const { proxy } = getCurrentInstance()!;
const map_ref = ref();
const allData = ref([]);
const echartsInstance = ref(null);

// 初始化echartsInstance对象
const initChart = async () => {
  echartsInstance.value = proxy!.$echarts.init(map_ref.value, themeStore.theme);
  // 获取中国地图的矢量数据
  //   const { data: res } = map;
  const { data: res } = await axios.get("http://localhost:8999/static/map/china.json");
  proxy!.$echarts.registerMap("china", res);
  const initOption = {
    title: {
      text: "▎ 商家分布",
      left: 20,
      top: 20
    },
    backgroundColor: getThemeValue(themeStore.theme).bgColor,
    geo: {
      type: "map",
      map: "china",

      itemStyle: {
        areaColor: "#2E72BF",
        borderColor: "#333"
      }
    },
    legend: {
      left: "5%",
      bottom: "5%",
      orient: "vertical"
    }
  };
  echartsInstance.value.setOption(initOption);

  echartsInstance.value.on("click", async arg => {
    // arg.name 得到所点击的省份, 这个省份他是中文
    const provinceInfo = getProvinceMapInfo(arg.name);
    // 需要获取这个省份的地图矢量数据
    // 判断当前所点击的这个省份的地图矢量数据在allData中是否存在
    if (!allData.value[provinceInfo.key]) {
      const ret = await axios.get("http://localhost:8999" + provinceInfo.path);
      allData.value[provinceInfo.key] = ret.data;
      proxy!.$echarts.registerMap(provinceInfo.key, ret.data);
    }
    const changeOption = {
      geo: {
        map: provinceInfo.key
      }
    };
    echartsInstance.value.setOption(changeOption);
  });
};

// 获取服务器的数据
const getData = async res => {
  allData.value = res;
  updateChart();
};

// 更新图表
const updateChart = () => {
  // 处理图表需要的数据
  // 图例的数据
  const legendArr = allData.value.map(item => {
    return item.name;
  });
  const seriesArr = allData.value.map(item => {
    // return的这个对象就代表的是一个类别下的所有散点数据
    // 如果想在地图中显示散点的数据, 我们需要给散点的图表增加一个配置, coordinateSystem:geo
    return {
      type: "effectScatter",
      rippleEffect: {
        scale: 5,
        brushType: "stroke"
      },
      name: item.name,
      data: item.children,
      coordinateSystem: "geo"
    };
  });
  const dataOption = {
    legend: {
      data: legendArr
    },
    series: seriesArr
  };
  echartsInstance.value.setOption(dataOption);
};

const screenAdapter = () => {
  const titleFontSize = (map_ref.value.offsetWidth / 100) * 3.6;
  const adapterOption = {
    title: {
      textStyle: {
        fontSize: titleFontSize
      }
    },
    tooltip: {
      axisPointer: {
        lineStyle: {
          width: titleFontSize
        }
      }
    },
    series: [
      {
        barWidth: titleFontSize,
        itemStyle: {
          borderRadius: [0, titleFontSize / 2, titleFontSize / 2, 0] // 设置圆角的大小
        }
      }
    ]
  };
  echartsInstance.value.setOption(adapterOption);
  // 手动的调用图表对象的resize 才能产生效果
  echartsInstance.value.resize();
};

const { themeStore } = useThemeChart(echartsInstance, initChart, updateChart, screenAdapter);

onMounted(() => {
  // 注册回调（使用可选链操作符）
  proxy.$socket.registerCallBack("mapData", getData);
  initChart();
  proxy.$socket.send({
    action: "getData",
    socketType: "mapData",
    chartName: "map",
    value: ""
  });
  window.addEventListener("resize", screenAdapter);
  // 在页面加载完成的时候, 主动进行屏幕的适配
  screenAdapter();
});
// 回到中国地图
const revertMap = () => {
  try {
    const revertOption = {
      geo: {
        map: "china"
      }
    };
    echartsInstance.value.setOption(revertOption);
  } catch (error) {}
};

onUnmounted(() => {
  // 在组件销毁的时候, 需要将监听器取消掉
  window.removeEventListener("resize", screenAdapter);
  // 注销回调（使用可选链操作符）
  proxy.$socket.unRegisterCallBack("mapData");
});

defineExpose({
  screenAdapter
});
</script>
